home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / dsp / dspgroup / dataio.arc / EMP.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1983-11-17  |  24.2 KB  |  735 lines

  1.  
  2. PROGRAM EPM( INPUT, OUTPUT, INFILE, DATAIO );
  3. (*===========================================================================*)
  4. (* This program converts 99000, 7000, and 320 load modules into binary       *)
  5. (* format and writes the binary values to the DATA I/O device.  The user is  *)
  6. (* prompted for the following information:                                   *)
  7. (*    1.  Load Bias - the offset to be applied when converting relocatable   *)
  8. (*        addresses to absolute addresses (in Hex.)                          *)
  9. (*    2.  4-bits or 8-bits - the user specifies if the chip being programmed *)
  10. (*        is a 4-bit or 8-bit chip.                                          *)
  11. (*    3.  Is the load module a 320 module - the 320 is word oriented and     *)
  12. (*        the offsets need to be converted internally from words to bytes.   *)
  13. (*    4.  Number of bytes/nibbles to send - the number of 8 or 4 bit values  *)
  14. (*        to be sent to the DATA I/O device (in Hex.)                        *)
  15. (*    5.  Inline or Parallel - Inline loads the bytes sequentially while     *)
  16. (*        Parallel loads every other byte into the DATA I/O.                 *)
  17. (*    5a. Msb or Lsb - applies only if Parallel is chosen. Msb will load the *)
  18. (*        most significant byte of each 16-bit word, Lsb will load the least *)
  19. (*        significant byte of each word.                                     *)
  20. (*    6.  Starting Address - the absolute address from which loading of the  *)
  21. (*        module into the DATA I/O is to begin (in Hex.)                     *)
  22. (*    7.  Continue (Y/N) - prompts if the user has more to download.         *)
  23. (*    8.  Need to load next phase - if the user has linked the object using  *)
  24. (*        overlays to specify pages, this will load the next phase into      *)
  25. (*        memory for the program to process.                                 *)
  26. (* Note:  The program assumes that the DATA I/O is configured in the system  *)
  27. (*        similar to a terminal, but the device may be allocated to lock     *)
  28. (*        out other users.  The allocation is done in the command procedure  *)
  29. (*===========================================================================*)
  30.  
  31. (*===========================================================================*)
  32. (* Modifications made to the program in migration to the Vax:  [TWG feb. 83] *)
  33. (*    1.  The ability to handle 7000 and 320 modules was added.              *)
  34. (*    2.  Compressed object can be handled as well as ASCII object.          *)
  35. (*    3.  Load modules with multiple phases are handled.                     *)
  36. (*    4.  4-bit and 8-bit downloading is handled in a single program.        *)
  37. (*    5.  The actual downloading to the DATA I/O is Vax specific.            *)
  38. (*===========================================================================*)
  39.  
  40. CONST
  41.    HEXF = 15;
  42.    HEXFF = 255;
  43.    HEX7FFF = 32767;
  44.    HEXFFFE = 65534;
  45.    HEXFFFF = 65535;
  46.    HEX10000 = 65536;
  47.    MEM_LENGTH = 131071;    (* 64K WORDS NEEDED FOR 320 *)
  48.    MESS0 = '**Error - Offset > Task Length ';
  49.    MESS1 = '**Error - Offset Must be Even ';
  50.    MESS2 = '**Error - Bad Input Data, Operation Aborted ';
  51.    MESS3 = '**Warning - Premature EOF Reached ';
  52.    MESS4 = '**Error - Operation Aborted by User ';
  53.    MESS5 = '**Error - Bad Tag,  , Operation Aborted, Tag = ';
  54.    MESS6 = 'Hit <CR> to continue when DATA I/O is ready ';
  55.    MESS7 = '**Error - Bad Data in File, Operation Aborted ';
  56.    MESS8 = '**Error - Checksum Error - Program Aborted ';
  57.    MESS9 = '**Error - DATA I/O Link in use - Program Aborted ';
  58.    MESSA = '**Error - Load Module Unavailable - Program ';
  59.  
  60. TYPE
  61.    BYTE = 0 .. HEXFF;
  62.    LONGINT = INTEGER;
  63.    ADDRESS = 0 .. 65535;
  64.    EMPTYPE = RECORD   (* USE TO KEEP (NESTED) SOURCE SO THE ORDER *)
  65.       END;            (* OF WORD'S FIELDS IS EASILY REVERSED      *)
  66.    WORD = PACKED RECORD
  67.       CASE INTEGER OF
  68.          0: ( I: ADDRESS );
  69.          1: ( START1: EMPTYPE;
  70.               BIT: 0 .. 1;
  71.               WDS: 0 .. HEX7FFF;
  72.               END1: EMPTYPE );
  73.          2: ( START2: EMPTYPE;
  74.               LOBYTE: 0 .. HEXFF;
  75.               HIBYTE: 0 .. HEXFF;
  76.               END2: EMPTYPE );
  77.  
  78.          3: ( START3: EMPTYPE;
  79.               LOCHAR: CHAR;
  80.               HICHAR: CHAR;
  81.               END3: EMPTYPE );
  82.          4: ( START4: EMPTYPE;
  83.               LOBYTELONIBBLE: 0 .. HEXF;
  84.               LOBYTEHINIBBLE: 0 .. HEXF;
  85.               HIBYTELONIBBLE: 0 .. HEXF;
  86.               HIBYTEHINIBBLE: 0 .. HEXF;
  87.               END4: EMPTYPE );
  88.          5: ( START5: EMPTYPE;
  89.               S: PACKED SET OF 0 .. 15;
  90.               END5: EMPTYPE );
  91.          6: ( START6: EMPTYPE;
  92.               T: PACKED ARRAY[ 0 .. 15 ] OF BOOLEAN;
  93.               END6: EMPTYPE );
  94.       END;
  95.    STR4 = PACKED ARRAY[ 1 .. 4 ] OF CHAR;
  96.    STR8 = PACKED ARRAY[ 1 .. 8 ] OF CHAR;
  97.    PATHNAME = PACKED ARRAY[ 1 .. 40 ] OF CHAR;
  98.  
  99.  
  100. VAR
  101.    INFILE: TEXT;
  102.    DATAIO: FILE OF BYTE;
  103.    MEM_ARRAY: PACKED ARRAY[ 0 .. MEM_LENGTH ] OF BYTE;
  104.    EVEN_BYTE, ODD_BYTE: BYTE;
  105.    NO_BYTES, OFFSET, XFER, MAX_LENGTH, BIAS: LONGINT;
  106.    PC: LONGINT;
  107.    LOAD_ADDR, ENTRY_POINT: LONGINT;
  108.    J: INTEGER;
  109.    BUFFER: INTEGER;
  110.    HEXIN: STR4;
  111.    CHKSUM: WORD;
  112.    COMPRESSED: BOOLEAN;
  113.    IS_320: BOOLEAN;
  114.    FOUR_BITS: BOOLEAN;
  115.    CONTINUE: BOOLEAN;
  116.    NEED_PHASE: BOOLEAN;
  117.    STAT: INTEGER;
  118.    IORP, MORL: CHAR;
  119.    REPLY: CHAR;
  120.    CH: CHAR;
  121.  
  122. PROCEDURE CHECKSUM( SUM: WORD ); FORWARD;
  123. PROCEDURE DISCONNECT; FORWARD;
  124. PROCEDURE HEXDEC( HXINPUT: STR4; VAR HXOUTPUT: LONGINT ); FORWARD;
  125. PROCEDURE INITDATAIO; FORWARD;
  126. PROCEDURE INITIALIZE; FORWARD;
  127. PROCEDURE LENGTH( BYTE_NO: LONGINT ); FORWARD;
  128. PROCEDURE LOAD; FORWARD;
  129. PROCEDURE READSCREEN; FORWARD;
  130. PROCEDURE SENDBLOCK; FORWARD;
  131. PROCEDURE WRDIO( BITS: BYTE ); FORWARD;
  132. PROCEDURE EXIST( P: PATHNAME; LENGTH: INTEGER; VAR STATUS: INTEGER );
  133.                                                             EXTERN;
  134.  
  135. PROCEDURE CHECKSUM(* ( SUM : WORD ) *);
  136.  
  137. (*===========================================================================*)
  138. (* Checksum writes to nil bytes to the DATA I/O followed by the Sum Check.   *)
  139. (* The sum check is also written to the output file along with the number of *)
  140. (* bytes transferred in decimal.                                             *)
  141. (*===========================================================================*)
  142.  
  143. VAR
  144.    A: ARRAY[ 1 .. 4 ] OF INTEGER;
  145.    C: INTEGER;
  146.  
  147. BEGIN
  148.    WRDIO( 0 );
  149.    WRDIO( 0 );
  150.    WRDIO( SUM.HIBYTE );
  151.    WRDIO( SUM.LOBYTE );
  152.    FOR C := 4 DOWNTO 1 DO
  153.       BEGIN
  154.       A[ C ] := SUM.I MOD 16;
  155.       SUM.I := SUM.I DIV 16;
  156.       END;
  157.    FOR C := 1 TO 4 DO
  158.       BEGIN
  159.       IF A[ C ] < 10 THEN
  160.          HEXIN[ C ] := CHR( A[ C ] + 48 )
  161.       ELSE
  162.          HEXIN[ C ] := CHR( A[ C ] + 55 );
  163.       END;
  164.    WRITELN( OUTPUT, 'Checksum = ', HEXIN );
  165.    WRITELN( OUTPUT, 'Bytes Transferred = ', XFER: 5 );
  166. END;
  167.  
  168. PROCEDURE DISCONNECT;
  169.  
  170. (*===========================================================================*)
  171. (* Disconnect simply prints a message that the program is terminating and    *)
  172. (* calls HALT if the termination is not normal.                              *)
  173. (*===========================================================================*)
  174.  
  175. BEGIN
  176.    WRITELN( OUTPUT, 'DATA I/O Download Link is Disconnected' );
  177.    WRITELN( OUTPUT, '***********Execution Ends***********' );
  178.    IF CONTINUE THEN                    (* PREMATURE TERMINATION *)
  179.       HALT;
  180. END;
  181.  
  182. PROCEDURE HEXDEC(* ( HXINPUT: STR4;
  183.                      VAR HXOUTPUT: LONGINT ) *);
  184.  
  185. (*===========================================================================*)
  186. (* HexDec converts a four character string representing a hex number into    *)
  187. (* an integer value.                                                         *)
  188. (*===========================================================================*)
  189.  
  190. CONST
  191.    HEX10 = 16;
  192.  
  193. VAR
  194.    K: INTEGER;
  195.    LENGTH: INTEGER;
  196.    NB: ARRAY[ 1 .. 4 ] OF INTEGER;
  197.  
  198. BEGIN
  199.    LENGTH := 4;
  200.    FOR K := 1 TO 4 DO
  201.       CASE HXINPUT[ K ] OF
  202.          '0': NB[ K ] := 0;
  203.          '1': NB[ K ] := 1;
  204.          '2': NB[ K ] := 2;
  205.          '3': NB[ K ] := 3;
  206.          '4': NB[ K ] := 4;
  207.          '5': NB[ K ] := 5;
  208.          '6': NB[ K ] := 6;
  209.          '7': NB[ K ] := 7;
  210.          '8': NB[ K ] := 8;
  211.          '9': NB[ K ] := 9;
  212.          'A', 'a': NB[ K ] := 10;
  213.          'B', 'b': NB[ K ] := 11;
  214.          'C', 'c': NB[ K ] := 12;
  215.          'D', 'd': NB[ K ] := 13;
  216.          'E', 'e': NB[ K ] := 14;
  217.          'F', 'f': NB[ K ] := 15;
  218.          ' ': LENGTH := LENGTH - 1;       (* Ignore Trailing Blanks *)
  219.          OTHERWISE
  220.             BEGIN
  221.             WRITELN( OUTPUT, MESS2 );
  222.             DISCONNECT;
  223.             END;
  224.          END; {CASE}
  225.    HXOUTPUT := 0;
  226.    FOR K := 1 TO LENGTH DO
  227.       HXOUTPUT := HXOUTPUT * HEX10 + NB[ K ];
  228. END;
  229.  
  230. PROCEDURE INITDATAIO;
  231.  
  232. (*===========================================================================*)
  233. (* InitDATAIO checks if the DATA I/O device is ready by calling the assembly *)
  234. (* language routine EXIST.  If the device is accessible, then a Pascal OPEN  *)
  235. (* is executed with the file name DATAIO being associated with the Vax       *)
  236. (* logical name DIO0:.  The command procedure assigns DIO0 to be the output  *)
  237. (* device.  Initial information needed by the DATA I/O as specified in the   *)
  238. (* manuals is also written.                                                  *)
  239. (*===========================================================================*)
  240.  
  241. CONST
  242.    PROM_DEV = 'DIO0:                                   ';
  243.    NAME_LEN = 5;
  244.  
  245. VAR
  246.    STATUS: INTEGER;
  247.  
  248. BEGIN
  249.    EXIST( PROM_DEV, NAME_LEN, STATUS );
  250.    IF STATUS = 0 THEN
  251.       BEGIN
  252.       OPEN( DATAIO, PROM_DEV, OLD );
  253.       REWRITE( DATAIO );
  254.       END
  255.    ELSE
  256.       BEGIN
  257.       WRITELN( OUTPUT, MESS9 );
  258.       HALT;
  259.       END;
  260.    WRDIO( 8 );
  261.    WRDIO( 28 );
  262.    WRDIO( 42 );
  263.    WRDIO( 73 );
  264.    WRDIO( 8 );
  265.    WRDIO( 0 );
  266. END;
  267.  
  268. PROCEDURE INITIALIZE;
  269.  
  270. (*===========================================================================*)
  271. (* Initialize prompts for needed information and assign the values needed to *)
  272. (* load the first phase into memory.                                         *)
  273. (*===========================================================================*)
  274.  
  275. CONST
  276.    FILENAME = 'INFILE                                  ';
  277.    NAME_LEN = 6;
  278.  
  279. VAR
  280.    CH: CHAR;
  281.    OVAL: BOOLEAN;
  282.    TRMNL: BYTE;
  283.    K: INTEGER;
  284.    STATUS: INTEGER;
  285.  
  286. BEGIN
  287.    WRITELN( OUTPUT, 'DATA I/O System 19 Prom Programmer Utility' );
  288.    CONTINUE := TRUE;
  289.    EXIST( FILENAME, NAME_LEN, STATUS );
  290.    IF STATUS = 0 THEN
  291.       BEGIN
  292.       OPEN( INFILE, FILENAME, OLD ); 
  293.       RESET( INFILE );
  294.       END
  295.    ELSE
  296.       BEGIN
  297.       WRITELN( OUTPUT, MESSA );
  298.       DISCONNECT;
  299.       END;
  300.    WRITELN( OUTPUT, 'Load Bias in Hex:' );
  301.    RESET( INPUT );
  302.    READ( INPUT, HEXIN );
  303.    HEXDEC( HEXIN, BIAS );
  304.    WRITELN( OUTPUT, '(4)-bits or (8)-bits at a time ? : ' );
  305.    READLN( INPUT );
  306.    READ( INPUT, CH );
  307.    FOUR_BITS := ( CH = '4' );
  308.    WRITELN( OUTPUT, 'Is the Load Module a 320 Module ( Y/N ) ? : ' );
  309.    READLN;
  310.    READ( INPUT, CH );
  311.    IS_320 := ( CH = 'Y' ) OR ( CH = 'y' );
  312.    FOR K := 0 TO MEM_LENGTH DO
  313.       MEM_ARRAY[ K ] := HEXFF;          (* INITIALIZE MEMORY *)
  314.    NEED_PHASE := TRUE;
  315. END;
  316.  
  317. PROCEDURE LENGTH(* ( BYTE_NO: LONGINT ) *);
  318.  
  319. (*===========================================================================*)
  320. (* Length writes the number of bytes to be transferred to the DATA I/O as    *)
  321. (* 4-bit (nibble) values as specified in the DATA I/O manuals.               *)
  322. (*===========================================================================*)
  323.  
  324.  VAR
  325.     SEND: WORD;
  326.  
  327. BEGIN
  328.    SEND.I := BYTE_NO;            (* SEND FOUR NIBBLE BYTE COUNT *)
  329.    WRDIO( SEND.HIBYTEHINIBBLE );
  330.    WRDIO( SEND.HIBYTELONIBBLE );
  331.    WRDIO( SEND.LOBYTEHINIBBLE );
  332.    WRDIO( SEND.LOBYTELONIBBLE );
  333.    WRDIO( 255 );
  334. END;
  335.  
  336. PROCEDURE LOAD;
  337.  
  338. (*===========================================================================*)
  339. (* Load reads records from the object module and processes the tags and data *)
  340. (* to convert the load module to a binary representation in memory. A whole  *)
  341. (* phase is ready into memory at one time and several operations may be done *)
  342. (* on the phase before a new one is read.                                    *)
  343. (* Note: special care of addresses must be taken for 320 modules.            *)
  344. (*===========================================================================*)
  345.  
  346. VAR
  347.    OBJ_REC: PACKED ARRAY [ 1 .. 80 ] OF CHAR;
  348.    K: INTEGER;
  349.    IDX: INTEGER;
  350.    NAME: STR8;
  351.    TAG: CHAR;
  352.    VAL: WORD;
  353.  
  354. PROCEDURE GETINT( VAR VAL: WORD; TAG: CHAR ); FORWARD;
  355.  
  356. PROCEDURE GETINT(* ( VAR VAL: WORD; TAG: CHAR ) *);
  357.  
  358. (*===========================================================================*)
  359. (* Getint obtains a 16-bit unsigned integer from the object record.          *)
  360. (*===========================================================================*)
  361.  
  362. VAR
  363.    TMPINT: ARRAY[ 0 .. 3 ] OF INTEGER;
  364.    CH: CHAR;
  365.    K: INTEGER;
  366.    CH_COUNT: INTEGER;
  367.  
  368. BEGIN                                                    (* GETINT *)
  369.    VAL.I := 0;
  370.    IF COMPRESSED THEN
  371.       BEGIN                (* GET THE VALUE INTO VAL *)
  372.       VAL.HICHAR := OBJ_REC[ IDX ];
  373.       IDX := IDX + 1;
  374.       IF TAG <> '*' THEN
  375.          BEGIN
  376.          VAL.LOCHAR := OBJ_REC[ IDX ];
  377.          IDX := IDX + 1;
  378.          END;
  379.       END
  380.    ELSE
  381.       BEGIN
  382.       IF TAG = '*' THEN
  383.          CH_COUNT := 1
  384.       ELSE
  385.          CH_COUNT := 3;
  386.       FOR K := 0 TO CH_COUNT DO
  387.          BEGIN
  388.          CH := OBJ_REC[ IDX ];
  389.          IDX := IDX + 1;
  390.          IF TAG <> '7' THEN
  391.             CHKSUM.I := CHKSUM.I - ORD( CH );
  392.          CASE CH OF
  393.             '0': TMPINT[ K ] := 0;
  394.             '1': TMPINT[ K ] := 1;
  395.             '2': TMPINT[ K ] := 2;
  396.             '3': TMPINT[ K ] := 3;
  397.             '4': TMPINT[ K ] := 4;
  398.             '5': TMPINT[ K ] := 5;
  399.             '6': TMPINT[ K ] := 6;
  400.             '7': TMPINT[ K ] := 7;
  401.             '8': TMPINT[ K ] := 8;
  402.             '9': TMPINT[ K ] := 9;
  403.             'A': TMPINT[ K ] := 10;
  404.             'B': TMPINT[ K ] := 11;
  405.             'C': TMPINT[ K ] := 12;
  406.             'D': TMPINT[ K ] := 13;
  407.             'E': TMPINT[ K ] := 14;
  408.             'F': TMPINT[ K ] := 15;
  409.             OTHERWISE
  410.                BEGIN
  411.                WRITELN( OUTPUT, MESS7 );
  412.                DISCONNECT;
  413.                END;
  414.             END;
  415.          END;
  416.       VAL.HIBYTEHINIBBLE := TMPINT[ 0 ];
  417.       VAL.HIBYTELONIBBLE := TMPINT[ 1 ];
  418.       VAL.LOBYTEHINIBBLE := TMPINT[ 2 ];
  419.       VAL.LOBYTELONIBBLE := TMPINT[ 3 ];
  420.       END;
  421. END;                                                     (* GETINT *)
  422.  
  423. BEGIN                                                      (* LOAD *)
  424.    COMPRESSED := FALSE;
  425.    CHKSUM.I := 0;
  426.    WRITELN( OUTPUT, '  **Loading of Object Module Begins**' );
  427.    READ( INFILE, OBJ_REC );
  428.    IDX := 1;
  429.    REPEAT
  430.       TAG := OBJ_REC[ IDX ];
  431.       IDX := IDX + 1;
  432.       IF TAG = CHR( 01 ) THEN
  433.          BEGIN
  434.          COMPRESSED := TRUE;
  435.          TAG := '0';
  436.          END;
  437.       IF ( TAG <> 'F' ) AND ( TAG <> ':' ) THEN
  438.          BEGIN
  439.          IF NOT COMPRESSED THEN
  440.             CHKSUM.I := CHKSUM.I - ORD( TAG );
  441.          GETINT( VAL, TAG );
  442.          END;
  443.       CASE TAG OF
  444.          '0', 'K', 'I':
  445.             BEGIN
  446.             IF NOT COMPRESSED THEN
  447.                FOR K := 0 TO 7 DO
  448.                   CHKSUM.I := CHKSUM.I - ORD( OBJ_REC[ IDX + K ] );
  449.             IDX := IDX + 8;
  450.             END;
  451.          '1', '2':
  452.             BEGIN
  453.             ENTRY_POINT := VAL.I;
  454.             IF TAG = '2' THEN
  455.                ENTRY_POINT := ENTRY_POINT + BIAS;
  456.             PC := ENTRY_POINT;
  457.             IF IS_320 THEN
  458.                PC := PC * 2;
  459.             END;
  460.          '3','4', '5', '6', 'G', 'H':
  461.             BEGIN
  462.             IF NOT COMPRESSED THEN
  463.                FOR K := 0 TO 5 DO
  464.                   CHKSUM.I := CHKSUM.I - ORD( OBJ_REC[ IDX + K ] );
  465.             IDX := IDX + 6;
  466.             END;
  467.          '7':
  468.             BEGIN
  469.             IF CHKSUM.I <> VAL.I THEN
  470.                BEGIN
  471.                WRITE( OUTPUT, MESS8 );
  472.                WRITELN( ' ': 5, VAL.I: 6, CHKSUM.I: 6 );
  473.                DISCONNECT;
  474.                END;
  475.             CHKSUM.I := 0;
  476.             END;
  477.          '8':
  478.             CHKSUM.I := 0;
  479.          '9', 'A':
  480.             BEGIN
  481.             LOAD_ADDR := VAL.I;
  482.             IF TAG = 'A' THEN
  483.                LOAD_ADDR := LOAD_ADDR + BIAS;
  484.             PC := LOAD_ADDR;
  485.             IF IS_320 THEN
  486.                PC := PC * 2; (* CONVERT WORD DISP TO BYTE DISP *)
  487.             END;
  488.          'B', 'C':
  489.             BEGIN
  490.             IF TAG = 'C' THEN
  491.                VAL.I := VAL.I + BIAS;
  492.             MEM_ARRAY[ PC ] := VAL.HIBYTE;
  493.             PC := PC + 1;
  494.             MEM_ARRAY[ PC ] := VAL.LOBYTE;
  495.             PC := PC + 1;
  496.             IF PC - 1 > MAX_LENGTH THEN
  497.                MAX_LENGTH := PC - 1;
  498.             END;
  499.          '*':
  500.             BEGIN
  501.             MEM_ARRAY[ PC ] := VAL.HIBYTE;
  502.             PC := PC + 1;
  503.             IF PC - 1 > MAX_LENGTH THEN
  504.                MAX_LENGTH := PC - 1;
  505.             END;
  506.          'D':
  507.             BEGIN
  508.             BIAS := VAL.I;
  509.             IF IS_320 THEN
  510.                BIAS := BIAS * 2;
  511.             IF BIAS MOD 2 <> 0 THEN
  512.                BIAS := BIAS + 1;
  513.             END;
  514.          'F':
  515.             BEGIN
  516.             READ( INFILE, OBJ_REC );
  517.             IDX := 1;
  518.             END;
  519.          ':': ;
  520.          OTHERWISE
  521.             BEGIN
  522.             WRITE( OUTPUT, MESS5 );
  523.             WRITELN( ' ': 5, TAG );
  524.             DISCONNECT;
  525.             END;
  526.          END;
  527.    UNTIL TAG = ':';
  528. END;                                                      (* LOAD *)
  529.  
  530. PROCEDURE READSCREEN;
  531.  
  532. (*===========================================================================*)
  533. (* ReadScreen obtains values needed to download the binary object in memory  *)
  534. (* into the DATA I/O.                                                        *)
  535. (*===========================================================================*)
  536.  
  537. VAR
  538.    K: INTEGER;
  539.    ERR: BOOLEAN;
  540.  
  541. BEGIN                                                   (* READSCREEN *)
  542.    REPEAT
  543.       WRITELN( OUTPUT, 'Number of Bytes/Nibbles to Send (Hex) : ' );
  544.       READLN;
  545.       READ( INPUT, HEXIN );
  546.       HEXDEC( HEXIN, NO_BYTES );
  547.    UNTIL NO_BYTES > 0;
  548.    WRITELN( OUTPUT, '(I)nline or (P)arallel ? : ' );
  549.    READLN;
  550.    READ( INPUT, IORP );
  551.    IF IORP = 'i' THEN
  552.       IORP := 'I';
  553.    IF IORP = 'p' THEN
  554.       IORP := 'P';
  555.    IF IORP = 'P' THEN
  556.       BEGIN
  557.       WRITELN( OUTPUT, '(M)sb or (L)sb ? : ' );
  558.       READLN;
  559.       READ( INPUT, MORL );
  560.       IF MORL = 'm' THEN
  561.          MORL := 'M';
  562.       IF MORL = 'l' THEN
  563.          MORL := 'L';
  564.       END;
  565.    REPEAT
  566.       ERR := FALSE;
  567.       WRITELN( OUTPUT, 'Starting Address (Hex) : ' );
  568.       READLN;
  569.       READ( INPUT, HEXIN );
  570.       HEXDEC( HEXIN, OFFSET );
  571.       IF ( OFFSET MOD 2 = 1 ) and not IS_320 THEN
  572.          BEGIN
  573.          ERR := TRUE;
  574.          WRITELN( OUTPUT, MESS1 );
  575.          END;
  576.    UNTIL ERR = FALSE;
  577. END;                                                  (* READSCREEN *)
  578.  
  579. PROCEDURE SENDBLOCK;
  580.  
  581. (*===========================================================================*)
  582. (* SendBlock ships the number of bytes specified by the user to the DATA I/O *)
  583. (* device.  If the object module is exhausted before the number of bytes is  *)
  584. (* reached, then a warning message is printed and values of HEXFF are sent   *)
  585. (* for the remaining bytes.                                                  *)
  586. (*===========================================================================*)
  587.  
  588. VAR
  589.    TMPWRD: WORD;
  590.    K: INTEGER;
  591.  
  592. BEGIN                                                      (* SENDBLOCK *)
  593.    CHKSUM.I := 0;
  594.    XFER := 0;
  595.    IF IS_320 THEN
  596.       J := OFFSET * 2                   (* Convert word to byte address *)
  597.    ELSE
  598.       J := OFFSET;
  599.    WHILE ( ( XFER < NO_BYTES ) AND ( J <= MAX_LENGTH ) ) DO
  600.       BEGIN
  601.       IF IORP = 'I' THEN
  602.          BEGIN
  603.          TMPWRD.HIBYTE := MEM_ARRAY[ J ];
  604.          IF FOUR_BITS THEN
  605.             BEGIN
  606.             WRDIO( TMPWRD.HIBYTEHINIBBLE );
  607.             WRDIO( TMPWRD.HIBYTELONIBBLE );
  608.             END
  609.          ELSE
  610.             WRDIO( TMPWRD.HIBYTE );
  611.          CHKSUM.I := CHKSUM.I + TMPWRD.HIBYTE;
  612.          J := J + 1;
  613.          TMPWRD.LOBYTE := MEM_ARRAY[ J ];
  614.          IF FOUR_BITS THEN
  615.             BEGIN
  616.             WRDIO( TMPWRD.LOBYTEHINIBBLE );
  617.             WRDIO( TMPWRD.LOBYTELONIBBLE );
  618.             END
  619.          ELSE
  620.             WRDIO( TMPWRD.LOBYTE );
  621.          CHKSUM.I := CHKSUM.I + TMPWRD.LOBYTE;
  622.          IF FOUR_BITS THEN
  623.             XFER := XFER + 4
  624.          ELSE
  625.             XFER := XFER + 2;
  626.          J := J + 1;
  627.          END
  628.       ELSE
  629.          IF MORL = 'M' THEN
  630.             BEGIN
  631.             TMPWRD.HIBYTE := MEM_ARRAY[ J ];
  632.             IF FOUR_BITS THEN
  633.                BEGIN
  634.                WRDIO( TMPWRD.HIBYTEHINIBBLE );
  635.                WRDIO( TMPWRD.HIBYTELONIBBLE );
  636.                END
  637.             ELSE
  638.                WRDIO( TMPWRD.HIBYTE );
  639.             CHKSUM.I := CHKSUM.I + TMPWRD.HIBYTE;
  640.             IF FOUR_BITS THEN
  641.                XFER := XFER + 2
  642.             ELSE
  643.                XFER := XFER + 1;
  644.             J := J + 2;
  645.             END
  646.          ELSE
  647.             IF MORL = 'L' THEN
  648.                BEGIN
  649.                IF J MOD 2 = 0 THEN
  650.                   J := J + 1;
  651.                TMPWRD.LOBYTE := MEM_ARRAY[ J ];
  652.                IF FOUR_BITS THEN
  653.                   BEGIN
  654.                   WRDIO( TMPWRD.LOBYTEHINIBBLE );
  655.                   WRDIO( TMPWRD.LOBYTELONIBBLE );
  656.                   END
  657.                ELSE
  658.                   WRDIO( TMPWRD.LOBYTE );
  659.                CHKSUM.I := CHKSUM.I + TMPWRD.LOBYTE;
  660.                IF FOUR_BITS THEN
  661.                   XFER := XFER + 2
  662.                ELSE
  663.                   XFER := XFER + 1;
  664.                J := J + 2;
  665.                END;
  666.       END;
  667.    IF J > MAX_LENGTH + 1 THEN
  668.          BEGIN
  669.          WRITELN( OUTPUT, XFER, NO_BYTES );
  670.          XFER := XFER + 1;
  671.          FOR K := XFER TO NO_BYTES DO
  672.             BEGIN
  673.             WRDIO( 0 );
  674.       {     CHKSUM.I := CHKSUM.I + 255;  }
  675.             END;
  676.          J := -1;
  677.          CHECKSUM( CHKSUM );
  678.          WRITELN( OUTPUT, MESS3 );
  679.          END
  680.    ELSE
  681.          BEGIN
  682.          J := -1;
  683.          CHECKSUM( CHKSUM );
  684.          END;
  685. END;                                                   (* SENDBLOCK *)
  686.  
  687. PROCEDURE WRDIO(* ( BITS: BYTE ) *);
  688.  
  689. (*===========================================================================*)
  690. (* Wrdio writes an 8-bit value to the DATA I/O device as a byte.             *)
  691. (*===========================================================================*)
  692.  
  693. BEGIN                                                      (* WRDIO *)
  694.    WRITE( DATAIO, BITS );
  695. END;                                                       (* WRDIO *)
  696.  
  697. BEGIN                                                        (* EPM *)
  698.    INITIALIZE;
  699.    REPEAT
  700.       IF NEED_PHASE THEN
  701.          LOAD;
  702.       READSCREEN;
  703.       WRITELN( OUTPUT, '  Enter the following on the DATA I/O:  ' );
  704.       WRITELN( OUTPUT, '  ' );
  705.       WRITELN( OUTPUT, '  SEL, 1, 0, ENTER, SEL, D, 1, START    ' );
  706.       WRITELN( OUTPUT, '  ' );
  707.       WRITELN( OUTPUT, MESS6 );
  708.       READLN( CH );          (* Wait for the user's response     *)
  709.       J := -1;
  710.       INITDATAIO;
  711.       J := -1;
  712.       LENGTH( NO_BYTES );
  713.       IF OFFSET > MAX_LENGTH THEN
  714.          BEGIN
  715.          WRITELN( OUTPUT, MESS0 );
  716.          CONTINUE := TRUE;
  717.          END
  718.       ELSE
  719.          BEGIN
  720.          SENDBLOCK;
  721.          CLOSE( DATAIO );
  722.          WRITELN( OUTPUT, 'Continue (Y/N) ? : ' );
  723.          READ( INPUT, REPLY );
  724.          CONTINUE := ( REPLY = 'Y' ) OR ( REPLY = 'y' );
  725.          END;
  726.       IF CONTINUE THEN
  727.          BEGIN
  728.          WRITELN( OUTPUT, 'Need to load next phase ? : ' );
  729.          READLN( INPUT );
  730.          READ( INPUT, REPLY );
  731.          NEED_PHASE := ( REPLY = 'Y' ) OR ( REPLY = 'y' );
  732.          END;
  733.    UNTIL NOT CONTINUE;
  734.    DISCONNECT;
  735. END.                                                          (* EPM *)